<?php
/**************************************************************************
 * Naanal PHP Framework, Simple, Efficient and Developer Friendly
 * Ver 3.0, Copyright (C) <2010>  <Tamil Amuthan. R>
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ************************************************************************/
function splitTag($tag)
{
	$arrParam=array();
	$arrEmptyParam=array(); 
	$arrToken=tokenizeTag($tag);  
	
	$tagName=array_shift($arrToken);
	$type="open";
        
	if(empty($arrToken))
	{
		if($tagName[0]=="/")
		{
			$type="end";
			$tagName=substr($tagName, 1);
		}
		return array("tag"=>$tagName,"param"=>$arrParam,"emptyparam"=>$arrEmptyParam,"type"=>$type);
	}
        $tmp="";
	do
	{
            //$tmp="";
		$key=array_shift($arrToken);
		$key=trim($key);
		if(isset($arrToken[0]) && (is_numeric($arrToken[0]) || !empty($arrToken[0])))
		{
			$tmp=$arrToken[0];
			$tmp=trim($tmp);
			if($tmp=="=")
			{        
				 $operator=array_shift($arrToken);
				 $val=array_shift($arrToken);
				 $arrParam[$key]=$val;
			}  
			else
			{
				if(is_numeric($tmp) || !empty($key)) $arrEmptyParam[]=$key;
			}
		}
		else
		{
			if(is_numeric($tmp) || !empty($key)) $arrEmptyParam[]=$key;
		}
	} while(!empty($arrToken));
	return array("tag"=>$tagName,"param"=>$arrParam,"emptyparam"=>$arrEmptyParam,"type"=>$type);
}

function processSmartyFunction($tag)
{
  $arrTag=splitString("|",$tag);
  $firstParam=array_shift($arrTag);
  $tagcount=count($arrTag);  
  for($i=0;$i<$tagcount;$i++)
  {
    $tg=$arrTag[$i];
    $arrTg=splitString(":",$tg);
    $function=array_shift($arrTg);
    if($function=="replace")
      $function="str_replace";
    else if($function=="regex_replace")
      $function="preg_replace";
    $arrParam=array();
    if(count($arrTg)>0)
    {
      for($vv=0;$vv<count($arrTg);$vv++)
      {
        if(empty($arrTg[$vv])) continue;
        $arrParam[]=$arrTg[$vv];//$this->convertSmartyVariableToPHP($arrTmp[$vv]);
      }
    }  
    
    if($function=="str_replace" || $function=="preg_replace")
    {
      $arrParam[]=$firstParam;
      $firstParam=$function.'( '.implode(',',$arrParam).' )';
    }
    else if($function == "cat")
    {
      $firstParam=implode('.',$arrParam);
    }
    else
    {
      array_unshift($arrParam, $firstParam);
      $firstParam=$function.'( '.implode(',',$arrParam).' )';
    }
  }
  return $firstParam;
}

///split string safely considering double quotes and single quotes
function splitString($splitBy,$str,$includeSplitString=false)
{
  $arrFinalStr=array();
  $strlen=strlen($str);
  $splitbylen=strlen($splitBy);
  $tmpstr="";
  for($i=0;$i<$strlen;$i++)
  {
    if($str[$i]=='"')
    {
      //$arrFinalStr[]=$tmpstr;
      $tmpstr=$tmpstr.$str[$i];
      for($j=$i+1;$j<$strlen;$j++)
      {
        $tmpstr=$tmpstr.$str[$j];
        if($str[$j]=='"' && $str[$j-1]!='\\')
        {
          $i=$j;
          break;
        }
      }
    }
    else if($str[$i]=="'")
    {
      //$arrFinalStr[]=$tmpstr;
      $tmpstr=$tmpstr.$str[$i];
      for($j=$i+1;$j<$strlen;$j++)
      {
        $tmpstr=$tmpstr.$str[$j];
        if($str[$j]=="'" && $str[$j-1]!='\\')
        {
          $i=$j;
          break;
        }
      }
    }
    else
    {
      for($m=0;$m<$splitbylen;$m++)
      {
        if($str[$i+$m]!=$splitBy[$m])
        { 
          break;
        }
      }
      ///if match found
      if($m==$splitbylen)
      {
        $arrFinalStr[]=$tmpstr;
        $tmpstr="";
        if($includeSplitString)
        {
          $arrFinalStr[]=$splitBy;
        }
        $i=$i+$splitbylen-1;
      }
      else
      {
        $tmpstr=$tmpstr.$str[$i];
      }
    }
  }
  $arrFinalStr[]=$tmpstr;  
  return $arrFinalStr;
}

function tokenizeTag($tag,$ignoreSpace=true)
{      
	$arrFinalTag=array();
	$arrTag=splitByStringQuotes($tag,$quoteChar=array('"',"'"));
       
	for($i=0;$i<count($arrTag);$i++)
	{
		if(empty($arrTag[$i]))
		{
			$arrFinalTag[]=$arrTag[$i];
		}
		else if($arrTag[$i][0]=='"' || $arrTag[$i][0]=="'")
		{
			$arrFinalTag[]=$arrTag[$i];
		}
		else
		{
			$tmp="";
			for($j=0;$j<strlen($arrTag[$i]);$j++)
			{   
        if($j===0 && $arrTag[$i][0]==" " && $ignoreSpace)
        {
           for($jj=0;$jj<strlen($arrTag[$i]);$jj++)
           {
              if($arrTag[$i][$jj]!=" ")
              {     
                $j=$jj;
                break;
              } 
           } 
        }   
				if($arrTag[$i][$j]==" ")
				{                    
					if($ignoreSpace) 
          { 
            if(is_numeric($tmp) || !empty($tmp)) $arrFinalTag[]=$tmp;
            $tmp="";
            $len=strlen($arrTag[$i]);
            for($jj=$j;$jj<$len;$jj++)
            {
              if($arrTag[$i][$jj]!=" ")
              {
                $j=$jj-1;   
                break;
              } 
            }
            if($jj==$len)
            {
              continue;
            }
          }   
          else
          {
             if(is_numeric($tmp) || !empty($tmp)) $arrFinalTag[]=$tmp;
             $tmp="";
             break;
          }
          if($ignoreSpace)
					for($m=$j;$m<strlen($arrTag[$i]);$m++)
					{    
						///skipping space
						if($arrTag[$i][$m]!=" ")
						{     
							$tmp="";
							break;	
						}  
					}
					$j=$m-1;
				}
				else if($arrTag[$i][$j]=="=" && isset($arrTag[$i][$j+1]) && $arrTag[$i][$j+1]=="=")
				{ 
          if(is_numeric($tmp) || !empty($tmp)) $arrFinalTag[]=$tmp;   
					$arrFinalTag[]="==";	
					$tmp=""; 
					$j=$j+1;
				}
				else if($arrTag[$i][$j]=="=")
				{  
					if(is_numeric($tmp) || !empty($tmp)) $arrFinalTag[]=$tmp;   
					$arrFinalTag[]="=";	
					$tmp="";
				}
				else
				{
					$tmp=$tmp.$arrTag[$i][$j];  
				}	
			}
			if(is_numeric($tmp) || !empty($tmp)) $arrFinalTag[]=$tmp; 
		}
	}
	return $arrFinalTag;	
}

function splitByPHPTag($str)
{
    $tagName="php";
    $tagDelimiterStart="<?";
    $tagDelimiterEnd="?>";
    $arrTag=array();
    $tmp="";
    $strlen=strlen($str);
    $tagDelimiterEndLen=strlen($tagDelimiterEnd);
    $tagDelimiterStartLen=strlen($tagDelimiterStart);
    for($i=0;$i<$strlen;$i++)
    {
        ///check whether delimiter start match
        for($ii=0;$ii<$tagDelimiterStartLen;$ii++)
        {
            if($str[$i+$ii]!=$tagDelimiterStart[$ii])
            {
                break;
            }
        }
        ///end
        ///if start delimiter matches
        if($ii===$tagDelimiterStartLen)
        { 
            $tagNameStart=$i+$tagDelimiterStartLen;
            ///check whether tagname matches
            $taglen=strlen($tagName); 
            for($j=0;$j<$taglen;$j++)
            {
                if($str[$tagNameStart+$j]!=$tagName[$j])
                {
                    break;
                }
            }
            ///if tag matched
            if($j===$taglen)
            {
                $arrTag[]=$tmp;
                $tmp="";
                $PHPTag=$tagDelimiterStart.$tagName;
                $isPHPTagExtracted=false;
                
                for($m=$tagNameStart+$taglen;$m<$strlen;$m++)
                {
                    ///skip any comments inside the tag
                    $skip=skipComment($str,$m,array('//','/*'));
                    if($skip!==false)
                    {
                        $PHPTag=$PHPTag.substr($str,$m,$skip-$m);
                        $m=$skip;
                    }
                    ///end
                    
                    ///skip any quotes inside the tag
                    $skip=skipQuotes($str,$m,"'");
                    if($skip!==false)
                    {
                        $PHPTag=$PHPTag.substr($str,$m,$skip-$m);
                        $m=$skip;
                    }
                    
                    $skip=skipQuotes($str,$m,'"');
                    if($skip!==false)
                    {
                        $PHPTag=$PHPTag.substr($str,$m,$skip-$m);
                        $m=$skip;
                    }
                    ///end
                    
                    ///check whether delimiter end match
                    for($mm=0;$mm<$tagDelimiterEndLen;$mm++)
                    {
                        if($str[$m+$mm]!=$tagDelimiterEnd[$mm])
                        {
                            break;
                        }
                    }
                    ///if delimiter end matches
                    if($mm===$tagDelimiterEndLen)
                    {
                        $arrTag[]=$PHPTag.$tagDelimiterEnd;
                        $i=$m+$tagDelimiterEndLen;
                        $isPHPTagExtracted=true;
                        break;
                    }
                    $PHPTag=$PHPTag.$str[$m];
                }
                /*///if opening tag is there and there is no closing php tag(? >)
                if(!$isPHPTagExtracted)
                {
                    $arrTag[]=$tmp;
                    $tmp="";
                }*/
            }
        }
        if(isset($str[$i])) $tmp=$tmp.$str[$i];
    }
    $arrTag[]=$tmp;
    return $arrTag;
}

function splitByTag($str,$arrTagNameOrStrTagName,$tagDelimiterStart="<", $tagDelimiterEnd=">")
{
    $arrTag=array();
    $tmp="";
    $strlen=strlen($str);
    if(!is_array($arrTagNameOrStrTagName))
    {
        $arrTagNameOrStrTagName=array($arrTagNameOrStrTagName);
    }
    for($i=0;$i<$strlen;$i++)
    {
        if($str[$i]==$tagDelimiterStart)
        {
            $isOpenTagFound=false;
            $taglen=-1;
            $tagName='';
            foreach($arrTagNameOrStrTagName as $tagName)
            {
                $taglen=strlen($tagName);
                if($taglen<=0) 
                {
                    $taglen=-1;
                    continue;
                }
                for($j=0;$j<$taglen;$j++)
                {
                    if($str[$i+$j+1]!=$tagName[$j])
                    {
                        break;
                    }
                }
                ///if tag matched
                if($j===$taglen)
                {
                    ///if tag perfectly matched
                    if($str[$i+$j+1]==" " || $str[$i+$j+1]=="\n" || $str[$i+$j+1]=="\r" || $str[$i+$j+1]==":" || $str[$i+$j+1]=="/")
                    {
                        $isOpenTagFound=true;
                        break;
                    }
                }
            }
            if($isOpenTagFound)
            {
                $hasEndTag=true;
                if(!empty($tmp))
                {
                    $arrTag[]=array("type"=>"text","content"=>$tmp);
                    $tmp=""; 
                }
                for($m=$i;$m<$strlen;$m++)
                {
                    $tmp=$tmp.$str[$m];
                    if($str[$m]==$tagDelimiterEnd)
                    {
                        if($str[$m-1]=="/")
                        {
                            $arrTag[]=array("type"=>$tagName,"content"=>$tmp);
                            $tmp="";
                            $hasEndTag=false;
                        }
                        ///point to last character of the tag. $tagDelimiterEnd(ex: '>')
                        $i=$m;
                        break;
                    }
                }
                ///search for end tag and extract
                if($hasEndTag)
                for($m=$i+1;$m<$strlen;$m++)
                {
                    if($str[$m]==$tagDelimiterStart && $str[$m+1]=="/")
                    {
                        //echo $str[$m].$str[$m+1].$str[$m+2].$str[$m+3].$str[$m+4].$str[$m+5].$str[$m+6].$str[$m+7].$str[$m+8].$str[$m+9]."-";
                        for($j=0;$j<$taglen;$j++)
                        {
                            if($str[$m+$j+2]!=$tagName[$j])
                            {
                                break;
                            }
                        }
                        ///if end tag matched
                        if($j===$taglen)
                        {
                            for(;$m<$strlen;$m++)
                            {
                                $tmp=$tmp.$str[$m];
                                if($str[$m]==$tagDelimiterEnd)
                                {
                                    $i=$m;
                                    break;
                                }
                            }
                            $arrTag[]=array("type"=>$tagName,"content"=>$tmp);
                            $tmp="";
                            break;
                        }
                    }
                    else
                    {
                        $tmp=$tmp.$str[$m];
                    }
                }
            }
            else
            {
                if(isset($str[$i])) $tmp=$tmp.$str[$i];
            }
        }
        else
        {
            if(isset($str[$i])) $tmp=$tmp.$str[$i];
        }
    }
    $arrTag[]=array("type"=>"text","content"=>$tmp);
    return $arrTag;
}

function splitByStringQuotes($str,$quoteChar=array('"'))
{
    if(!is_array($quoteChar))
    {
        $quoteChar=array($quoteChar);
    }
    $arrContent=array();
    $start=0;
    for($i=0;$i<strlen($str);$i++)
    {
      if(in_array($str[$i], $quoteChar))
      {
          $quoteCharSelect=$str[$i];
          $arrContent[]=substr($str, $start,$i-$start);
          $start=$i;
          for($j=$i+1;$j<strlen($str);$j++)
          {
             if($str[$j]==$quoteCharSelect && $str[$j-1]!='\\') 
             {
                 $arrContent[]=substr($str, $i,$j-$i+1);
                 $i=$j;
                 $start=$i+1;
                 break;
             }
          }
      }
    }
    $arrContent[]=substr($str,$start);
    return $arrContent;
}

function skipQuotes($str,$index,$quoteChar=array('"'))
{
    if(!is_array($quoteChar))
    {
        $quoteChar=array($quoteChar);
    }
    $i=$index;
    if(in_array($str[$i], $quoteChar))
    {
      $quoteCharSelect=$str[$i];
      for($j=$i+1;$j<strlen($str);$j++)
      {
         if($str[$j]==$quoteCharSelect && $str[$j-1]!='\\') 
         {
             return $j+1;
         }
      }
      return $j;
    }
    return false;
}

function skipComment($content,$index,$arrCommentTag=array('//','/*','<!--'))
{
    $i=$index;
    if(in_array('//',$arrCommentTag) && $content[$i]=='/' && $content[$i+1]=='/')
    {
        $isSingleComment=true;
        $start=$i;
        for($j=$i+1;$j<strlen($content);$j++)
        {
            if($content[$j]=="\n")
            {
                return $j;
            }
        }
        return $j;
    }
    else if(in_array('/*',$arrCommentTag) && $content[$i]=='/' && $content[$i+1]=='*')
    {
        $isMultipleComment=true;
        for($j=$i+2;$j<strlen($content);$j++)
        {
            if($content[$j]=='*' && $content[$j+1]=='/')
            {
                return $j+2;
            }
        }
        return $j;
    }
    else if(in_array('{*',$arrCommentTag) && $content[$i]=='{' && $content[$i+1]=='*')
    {
        $isMultipleComment=true;
        for($j=$i+2;$j<strlen($content);$j++)
        {
            if($content[$j]=='*' && $content[$j+1]=='}')
            {
                return $j+2;
            }
        }
        return $j;
    }
    else if(in_array('<!--',$arrCommentTag) && $content[$i]=='<' && $content[$i+1]=='!' && $content[$i+2]=='-' && $content[$i+3]=='-')
    {
        $isMultipleComment=true;
        $start=$i;
        for($j=$i+1;$j<strlen($content);$j++)
        {
            if($content[$j]=='-' && $content[$j+1]=='-' && $content[$j+2]=='>')
            {
                return $j+3;
            }
        }
        return $j;
    }
    else
    {
        return false;
    }
}
function splitByComment($content,$arrCommentTag=array('//','/*','<!--'))
{
    $arrContent=array();
    $start=0;
    $isSingleComment=false;
    $isMultipleComment=false;
    $isSingleDocumentComment=false;
    $isMultipleDocumentComment=false;
    
    for($i=0;$i<strlen($content);$i++)
    {
        if(in_array('//',$arrCommentTag) && $content[$i]=='/' && $content[$i+1]=='/')
        {
            $isSingleComment=true;
            $arrContent[]=substr($content, $start,$i);
            $start=$i;
            for($j=$i+1;$j<strlen($content);$j++)
            {
                if($content[$j]=="\n")
                {
                    $arrContent[]=substr($content, $start,$j-$start);
                    $i=$j;
                    $start=$i+1;
                    break;
                }
            }
        }
        else if(in_array('/*',$arrCommentTag) && $content[$i]=='/' && $content[$i+1]=='*')
        {
            $isMultipleComment=true;
            $arrContent[]=substr($content, $start,$i-$start);
            for($j=$i+2;$j<strlen($content);$j++)
            {
                if($content[$j]=='*' && $content[$j+1]=='/')
                {
                    $arrContent[]=substr($content, $i,$j-$i+2);
                    $i=$j+1;
                    $start=$i+1;
                    break;
                }
            }
        }
        else if(in_array('{*',$arrCommentTag) && $content[$i]=='{' && $content[$i+1]=='*')
        {
            $isMultipleComment=true;
            $arrContent[]=substr($content, $start,$i-$start);
            for($j=$i+2;$j<strlen($content);$j++)
            {
                if($content[$j]=='*' && $content[$j+1]=='}')
                {
                    $arrContent[]=substr($content, $i,$j-$i+2);
                    $i=$j+1;
                    $start=$i+1;
                    break;
                }
            }
        }
        else if(in_array('<!--',$arrCommentTag) && $content[$i]=='<' && $content[$i+1]=='!' && $content[$i+2]=='-' && $content[$i+3]=='-')
        {
            $isMultipleComment=true;
            $arrContent[]=substr($content, $start,$i);
            $start=$i;
            for($j=$i+1;$j<strlen($content);$j++)
            {
                if($content[$j]=='-' && $content[$j+1]=='-' && $content[$j+2]=='>')
                {
                    $arrContent[]=substr($content, $start,$j-$start+2);
                    $i=$j+2;
                    $start=$i+1;
                    break;
                }
            }
        }
    }
    $arrContent[]=substr($content,$start);
    return $arrContent;
}
?>